//给多级子元素赋值
const nextRelationAdd = (conData, pIds, nextRelationChildren) => {
  if (!pIds.length) {
    conData.children = [...conData.children, ...nextRelationChildren]
    return
  }
  let parentRelationData = conData.children.find(item => item.id == pIds[0])
  if (!parentRelationData) {
    parentRelationData = {id: pIds[0], model: "relationCon", children: []}
    conData.children.push(parentRelationData)
  }
  if (pIds.length == 1) parentRelationData.children = [...parentRelationData.children, ...nextRelationChildren]
  pIds.shift()
  if (!pIds.length) return;
  nextRelationAdd(parentRelationData, pIds, nextRelationChildren)
}

let genObj = {
  state: 0,
  charValue: "",
  curRelationIds: [],//当前父级的id列表
  curRelationList: [],//当前的relationCon的children里面的数据
  //正式的数据
  mConData: {
    model: "relationCon",
    children: []
  },
  generateId() {
    let color = "", letters = "0123456789ABCDEF"
    for (let i = 0; i < 5; i++) {
      color += letters[Math.floor(Math.random() * 16)]
    }
    return new Date().getTime() + color
  },
  startConData(char) {
    this.state = this.state == 0 ? 1 : 0
    this.readValue(char)
  },
  endConData(char) {
    if (this.state == 1 && this.charValue.split(" ").length > 1) {//当前要结束了，保存数据
      let [lable, condition, value] = this.charValue.split(" ")
      lable = lable.replace(/['#']/g, "")
      let valueConItem = {id: this.generateId(), model: "valueCon"}
      valueConItem.value = {lable, value, condition}
      valueConItem.valueStr = this.charValue
      this.curRelationList.push(valueConItem)
    }
    if (this.state == 1 && containsStr(relationList, char)) {
      let connectParaItem = {model: "connectPara"}
      connectParaItem.command = char
      this.curRelationList.push(connectParaItem)
      this.charValue = ""
      if (this.curRelationList.length == 1) {//如果当前数组中只有一个连接符则将当前数据放到正式数据里面
        nextRelationAdd(this.mConData, JSON.parse(JSON.stringify(this.curRelationIds)), this.curRelationList, true)
        this.curRelationList = []
      }
    }
    this.state = this.state == 0 ? 1 : 0
  },
  readValue(char) {
    if (this.state == 1) {
      this.charValue += " " + char
    }
  },
  startAddChild() {
    if (this.curRelationList.length > 1) {
      nextRelationAdd(this.mConData, JSON.parse(JSON.stringify(this.curRelationIds)), this.curRelationList)
      this.curRelationList = []
    }
    this.curRelationIds.push(this.generateId())
  },
  endAddChild(char) {
    this.endConData(char)
    this.charValue = ""
    this.state = 1
    nextRelationAdd(this.mConData, JSON.parse(JSON.stringify(this.curRelationIds)), this.curRelationList)
    this.curRelationList = []
    this.curRelationIds.pop()
  }
}

const containsStr = (list, value) => {
  // console.log("containsStr", list, value)
  return list.find(item => value.indexOf(item) != -1)
}
let conList = ['>', '<', '==', '!==', 'contains']
let relationList = ['and', 'or']

let str = "( #a < 3 and ( #w < 3 and #zz < 2 ) or #e contains 3 ) and ( #b == 5 or #z > 3 )"
// let str = "( #a < 3 or #e contains 3 ) and ( #b == 5 or #z > 3 )"
// let str = "#ww < 3 and #zz < 2"
str = str.split(" ")

for (let i = 0; i < str.length; i++) {
  let char = str[i]
  if (char.indexOf("(") != -1) {
    genObj.startAddChild(char)
  } else if (char.indexOf(")") != -1) {
    genObj.endAddChild(char)
  } else if (char.indexOf('#') != -1) {
    genObj.startConData(char)
  } else if (containsStr(relationList, char)) {
    genObj.endConData(char)
  } else {
    genObj.readValue(char)
  }
  if (i == str.length - 1 && char.indexOf(")") == -1) {
    genObj.endAddChild(char)
  }
  console.log("\n")
  console.log("char====", i, char)
  console.log("char====", genObj.state, genObj.charValue)
  console.log("char====", genObj.curRelationIds, JSON.stringify(genObj.curRelationList))
  console.log(JSON.stringify(genObj.mConData))
}
